/*
 *    uart0.c  -  uart0 api & driver
 *
 *	  Board:		akae2440
 *    environment:	bootloader & ADS
 *    Author:		akaedu
 *    Date:			2009-5-26
 *    web:			www.akaedu.org
 *
 *  
 *	  GPIO address_MAP
 *	  
 *	  CPLD_MAP_BASE	physical address is	0x20800000		
 *	  CPLD_LED		physical address is	0x20800000		
 *	  CPLD_SEG		physical address is	0x20800080
 *	  CPLD_DIP		physical address is	0x208000a0
 *
 *	  GPIO port_MAP
 *
 *	  GPA_PORT~GPB_PORT(130 multi-functional input port pins)
 *	  GPIO_BASE	:	GPACON	:	0x56000000	
 *
 *	  NAME			GPIO		CPLD_IN		CPLD_OUT	GPIO_CON		MODE_bit_CON	GPIO_DAT		MODE_bit_DAT		
 *	  BEEP			GPB0		TOUT0		BEEP		0x56000010		[1:0]			0x56000014		[0]
 *
 *	  GPIO key_scn_MAP
 *
 *	  NAME			PORT_OUT			PORT_IN			
 *	  KEY(sw1)		KBOUT1 : GPB8		KBIN1 : ENT0 : GPF0				
 *	  KEY(sw2)		KBOUT0 : GPB9		KBIN1 : ENT0 : GPF0			
 *	  KEY(sw3)		KBOUT1 : GPB8		KBIN0 : ENT2 : GPF2				
 *	  KEY(sw4)		KBOUT1 : GPB8		KBIN1 : ENT2 : GPF2				
 *
 *	  GPIO_CON						GPIO_DAT				GPIO		MODE_bit_CON		MODE_bit_DAT
 *	  GPBCON : 0x56000010			GPBDAT : 0x56000014		GPB8		[17:16]				[8]			
 *	  GPBCON : 0x56000010			GPBDAT : 0x56000014		GPB9		[19:18]				[9]			
 *	  GPFCON : 0x56000050			GPBDAT : 0x56000054		GPF0		[1:0]				[0]			
 *	  GPFCON : 0x56000050			GPBDAT : 0x56000054		GPF2		[5:4]				[2]			
 *
 *	  UART
 *	  ULCON0	: 0x50000000
 *	  UCON0		: 0x50000004
 *	  UFCON0	: 0x50000008
 *	  UMCON0	: 0x5000000c
 *	  UTRSTAT0	: 0x50000010
 *	  UERSTAT0	: 0x50000014
 *	  UFSTAT0	: 0x50000018
 *	  UMSTAT0	: 0x5000001c
 *	  UTXH0		: 0x50000020
 *	  URXH0		: 0x50000024
 *	  UBRDIV0	: 0x50000028
 *
 *
 */
#include "uart0.h"

/*uart Special Registers off_size*/
#define UART0_BASE		(0x50000000)
#define UART1_BASE		(0x50004000)

#define ULCON			0x00
#define UCON			0x04
#define UFCON			0x08
#define UMCON			0x0c
#define UTRSTAT			0x10
#define UERSTAT			0x14
#define UFSTAT			0x18
#define UMSTAT			0x1c
#define UTXH			0x20
#define URXH			0x24
#define UBRDIV			0x28

/* UART Status Register bits */
#define UTRSTAT_T_EMPTY		(1 << 2)
#define UTRSTAT_BUF_EMPTY	(1 << 1)
#define UTRSTAT_R_READY		(1 << 0)

#define ULCON0			*((volatile unsigned int *)(UART0_BASE+ULCON))
#define UCON0			*((volatile unsigned int *)(UART0_BASE+UCON))
#define UFCON0			*((volatile unsigned int *)(UART0_BASE+UFCON))
#define UMCON0			*((volatile unsigned int *)(UART0_BASE+UMCON))
#define UBRDIV0			*((volatile unsigned int *)(UART0_BASE+UBRDIV))
#define UTRSTAT0		*((volatile unsigned int *)(UART0_BASE+UTRSTAT))
#define UTXH0			*((volatile unsigned int *)(UART0_BASE+UTXH))
#define URXH0			*((volatile unsigned int *)(UART0_BASE+URXH))

/*
#define ULCON0			*((volatile unsigned int *)0x50000000)
#define UCON0			*((volatile unsigned int *)0x50000004)
#define UFCON0			*((volatile unsigned int *)0x50000008)
#define UMCON0			*((volatile unsigned int *)0x5000000c)
#define UBRDIV0			*((volatile unsigned int *)0x50000028)
#define UTRSTAT0		*((volatile unsigned int *)0x50000010)
#define UTXH0			*((volatile unsigned int *)0x50000020)
#define URXH0			*((volatile unsigned int *)0x50000024)
*/

#define GPHCON			*((volatile unsigned int *)(0X56000070))
#define GPHDAT			*((volatile unsigned int *)(0X56000074))

int uart0_init(void)
{
	GPHCON = 0x00faaa;
	GPHDAT = 0x7ff;
	/* 8 N 1 */
	ULCON0=3;
	/* interrupt request or polling mode */
	UCON0 = 5;
	/* init UFCON0 UMCON0 */
	UFCON0 = 0;
	UMCON0 = 0;
	/*
	* UBRDIV = PCLK/(baudrate * 16) - 1
	* PCLK = 50.7Mhz
	*
	* baudrate 115200 
	*/
	UBRDIV0 = 27;

	return 0;
}

char uart0_getchar(void)
{
	char ch;
	
	while (!(UTRSTAT0 & UTRSTAT_R_READY))
		;
	ch = URXH0;
	
	return ch;
}

int uart0_putchar(char ch)
{
	while (!(UTRSTAT0 & UTRSTAT_T_EMPTY))
		;
		
	UTXH0= ch;
	
	return 0;
}

int uart0_test(void)
{
	char ch;

	uart0_init();
	
	uart0_putchar('u');
	uart0_putchar('a');
	uart0_putchar('r');
	uart0_putchar('t');
	uart0_putchar('0');
	
	while(1)
	{
		ch = uart0_getchar();
		uart0_putchar(ch);
	}
	
	return 0;
}

